package com.xsky.table.impl;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

public class TableConfiguration
{
	private Map<String, Table> tables = new HashMap<String, Table>();

	private static TableConfiguration instance = null;

	public static synchronized TableConfiguration getInstance() throws DocumentException, IOException
	{

		if (instance == null)
		{
			instance = new TableConfiguration();
			instance.configure();
		}

		return instance;
	}


	public Table getTable(String tableName)
	{
		return tables.get(tableName);
	}

	private TableConfiguration()
	{

	}

	private void configure() throws DocumentException, IOException
	{
		this.configure(TableConfiguration.class.getResourceAsStream("/config/tables.xml"));
	}

	private void configure(InputStream in) throws DocumentException, IOException
	{

		tables.clear();

		String text = this.getText(in);

		Document doc = DocumentHelper.parseText(text);

		Iterator tableIterator = doc.getRootElement().elementIterator("table");

		while (tableIterator.hasNext())
		{
			Element tableElement = (Element) tableIterator.next();

			String tableName = tableElement.attributeValue("name");

			Table table = new Table();

			Map<String, Column> columns = table.getColumns();
			Map<String, Column> labels = table.getLabels();
			ArrayList<Column> columnList = table.getColumnList();

			List<String> pks = new ArrayList<String>();

			Iterator columnIterator = tableElement.elementIterator("//table/columns/column");

			while (columnIterator.hasNext())
			{
				Element columnElement = (Element) columnIterator.next();

				String columnName = columnElement.attributeValue("name");
				String columnLabel = columnElement.attributeValue("label");
				String columnType = columnElement.attributeValue("type");
				String seq = columnElement.attributeValue("seq");
				boolean isPk = Boolean.valueOf(columnElement.attributeValue("pk"));

				Column column = new Column();
				column.setLabel(columnLabel);
				column.setName(columnName);
				column.setType(columnType);
				column.setPk(isPk);
				column.setXml(columnElement);

				column.setSeq(Integer.valueOf(seq));

				if (isPk)
				{
					pks.add(columnName);
				}

				columnList.add(column);

				columns.put(columnName, column);
				labels.put(columnLabel, column);
				labels.put(seq, column);
			}

			Collections.sort(columnList);

			table.setPrimaryKeys(pks.toArray(new String[0]));
			table.setXml(tableElement);
			tables.put(tableName, table);
		}

	}

	private String getText(InputStream in) throws IOException
	{
		ByteArrayOutputStream bout = new ByteArrayOutputStream();

		byte[] buffer = new byte[1024];

		int num = in.read(buffer);

		while (num > 0)
		{
			bout.write(buffer, 0, num);
			num = in.read(buffer);
		}
		return new String(bout.toByteArray(), "utf-8");
	}

	public static void main(String[] args) throws IOException
	{
		try
		{
			new TableConfiguration().configure();
		} catch (DocumentException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
